/*
 * @Descripttion:
 * @version:
 * @Author: 周凯
 * @Date: 2020-05-04 15:10:37
 * @LastEditors: 周凯
 * @LastEditTime: 2020-05-11 11:59:34
 */
import {
  Scene,
  PerspectiveCamera,
  WebGLRenderer,
  BoxGeometry,
  MeshBasicMaterial,
  Mesh,
  TextureLoader,
  DoubleSide,
  Material,
  SpotLight,
} from "three";
import Stats from "stats.js";
import { OrbitControls } from "../utils/OrbitControls";
import { WEBGL } from "../utils/compatibility";

// 图片资源引入
// @ts-ignore
import rt from "/assets/skybox/rt.png";
// @ts-ignore
import lf from "/assets/skybox/lf.png";
// @ts-ignore
import up from "/assets/skybox/up.png";
// @ts-ignore
import dn from "/assets/skybox/dn.png";
// @ts-ignore
import bk from "/assets/skybox/bk.png";
// @ts-ignore
import ft from "/assets/skybox/ft.png";
// @ts-ignore
import texture from "/assets/texture.jpg";

export class Application {
  private scene: Scene;
  private camera: PerspectiveCamera;
  private renderer: WebGLRenderer;
  private width: number;
  private height: number;
  private stats: any;
  constructor() {
    // 获取宽度，高度
    this.width = window.innerWidth;
    this.height = window.innerHeight;

    // 场景
    this.scene = new Scene();
    // 透视相机
    this.camera = new PerspectiveCamera(
      45,
      this.width / this.height,
      0.1,
      1000
    );
    // 设置相机位置
    this.camera.position.set(0, 0, 20);
    // 渲染
    this.renderer = new WebGLRenderer({
      // 抗锯齿
      antialias: true,
    });

    // 设置舞台大小
    this.renderer.setSize(this.width, this.height);
    // canvas添加到body中
    // @ts-ignore
    window.document
      .getElementById("root")
      .appendChild(this.renderer.domElement);
    /**
     * 检测浏览器兼容性
     */
    if (WEBGL.isWebGLAvailable()) {
      this.renderStats();
      this.RenderOrbitControls();
      this.Resize();
      this.Model();
      this.light();
      this.render();
      console.log(this.scene);
    } else {
      const warning = WEBGL.getWebGLErrorMessage();
      document.getElementById("root")?.appendChild(warning);
    }
  }
  // 平行光
  private light() {
    console.log(this.scene, "sce");
    console.log(this.scene.getObjectByName("box"));
    var spotLight = new SpotLight(0xffffff);
    spotLight.position.set(0, 1, 1);

    spotLight.castShadow = true;

    spotLight.shadow.mapSize.width = 1024;
    spotLight.shadow.mapSize.height = 1024;

    spotLight.shadow.camera.near = 500;
    spotLight.shadow.camera.far = 4000;
    spotLight.shadow.camera.fov = 30;

    this.scene.add(spotLight);
  }
  // 加载轨道控制器
  private RenderOrbitControls() {
    const orbitControls = new OrbitControls(
      this.camera,
      this.renderer.domElement
    );
  }
  // 加载指示器
  private renderStats() {
    this.stats = new Stats();
    this.stats.showPanel(0);
    // @ts-ignore
    window.document.getElementById("root").appendChild(this.stats.dom);
  }
  // 监听window resize动态窗体变化
  private Resize() {
    window.addEventListener("resize", () => {
      this.renderer.setSize(window.innerWidth, window.innerHeight);
      this.camera.aspect = window.innerWidth / window.innerHeight;
      this.camera.updateProjectionMatrix();
    });
  }
  // 模型(几何图形...)
  private Model() {
    // 图片材质加载
    const textureLoader = new TextureLoader();
    const boxTexture = textureLoader.load(
      texture,
      function (texture) {
        console.log(texture, "加载成功");
      },
      undefined,
      function (error) {
        console.log(error, "加载失败");
      }
    );
    // 加载最外层box
    const skyBoxGenomtry = new BoxGeometry(200, 200, 200);
    const skyMaterials: Material[] = [];
    const images: any[] = [rt, lf, up, dn, bk, ft];
    images.forEach((item) => {
      skyMaterials.push(
        new MeshBasicMaterial({
          map: textureLoader.load(item),
          side: DoubleSide,
        })
      );
    });

    const skyMesh = new Mesh(skyBoxGenomtry, skyMaterials);
    skyMesh.name = "skyBox";
    this.scene.add(skyMesh);
    // 立方几何体
    const boxGenomtry = new BoxGeometry(1, 1, 1);

    // 材质
    const meshBasicMaterial = new MeshBasicMaterial({
      map: boxTexture,
      side: DoubleSide,
    });
    // 网格
    const mesh = new Mesh(boxGenomtry, meshBasicMaterial);
    mesh.name = "box";
    this.scene.add(mesh);
  }
  // 渲染
  private render() {
    // (保持刷新)
    window.requestAnimationFrame(() => this.render());
    // 渲染指示器
    this.stats.begin();
    // const skyBox = this.scene.getObjectByName("skyBox");
    // @ts-ignore
    // skyBox.rotation.y += 0.001;
    const box = this.scene.getObjectByName("box");
    box.rotation.x += 0.01;
    box.rotation.y += 0.01;
    box.rotation.z += 0.01;
    // 渲染
    this.renderer.render(this.scene, this.camera);
    this.stats.end();
  }
}
